package com.kellycheung.chicken_go_go;

import java.util.ArrayList;

import org.json.JSONObject;

import com.kellycheung.chicken_go_go.BaseObject.GOAnchor;
import com.kellycheung.chicken_go_go.GTouchPoint.TouchAction;

import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.R.color;
import android.graphics.Canvas;
import android.graphics.Paint.Align;
import android.view.MotionEvent;

public class GameScene {
	public enum GameSceneStatus {
		none(-1), all(0), loading(1)
		,ghNormal(101), ghExit(102)
			,ghFeed(111), ghFeedConfirm(112), ghFeedGoShop(113)
			,ghRace(121), ghMultiWait(122), ghMultiServerWait(123), ghMultiServerOK(123), ghMultiClientWait(125), ghTutor(126), ghRaceStage(127)
			,ghShop(131), ghShopConfirm(132),ghShopBuyErr(133)
			,ghCredit(141), ghSetting(142), ghSoundControl(143)
		,grPrepare(201), grNormal(202), grPause(203), grConfirmExit(204), grConfirmBack(205)
			,grGameWin(211), grGameOver(212)
		,grFirst(301),grSecond(302),grThird(303),grLoss(304), grWaiting(305), grStartGame(306)
		;
		
		private final int iVal;
		
		private GameSceneStatus( int p_iVal ) { 
			this.iVal = p_iVal; 
		}
		
		public int getVal() {
			return this.iVal;
		}
		
		public static boolean IsAllowRun( GameSceneStatus p_scsObj , GameSceneStatus p_scsScene ) {
			if ( p_scsObj == GameSceneStatus.all ) {
				return true;
			}
			else {
				switch (p_scsScene) {
				case ghNormal:
				case grNormal:
					return true;
				default:
					if ( p_scsObj == p_scsScene ) {
						return true;
					}
					break;
				}
			}
			
			return false;
		}
	}

	protected static final int I_THIS_CNT = 9;
	
	protected GameEngine geMain;
	protected String[] sParm;
	protected JSONObject joNetwork;
	
	protected ArrayList<BaseObject> alboBackGround;
	protected ArrayList<BaseObject> alboForeGround;
	protected ArrayList<BaseObject> alboSceneObj;
	protected ArrayList<ClickableObj> alcoClickableObj;
	protected ArrayList<GMenu> algmMenuList;
	protected GMenu gmNowShowing;
	
	protected int iFistTouchPointIdx;
	protected GameSceneStatus gssStatus;
	protected int iLoadCnt;
	protected int iLoadTotal;
	protected int iResBGMusic;
	protected GameSceneStatus gssStatusNormal;
	protected boolean bIsAnyBTConnectionCreated;
	
	public GameScene( GameEngine p_geMain , int p_iExtraLoad , String[] p_sParm ) {
		try {
			this.gssStatus = GameSceneStatus.loading;
			this.gssStatusNormal = GameSceneStatus.loading;
			
			this.iLoadTotal = GameScene.I_THIS_CNT + p_iExtraLoad;
					
			this.iLoadCnt = 0;
			this.geMain = p_geMain;
			this.sParm = p_sParm;
			this.iLoadCnt++;
			
			this.joNetwork = new JSONObject();
			
			this.alboBackGround = new ArrayList<BaseObject>();
			this.iLoadCnt++;
			this.alboForeGround = new ArrayList<BaseObject>();
			this.iLoadCnt++;
			this.alboSceneObj = new ArrayList<BaseObject>();
			this.iLoadCnt++;
			this.alcoClickableObj = new ArrayList<ClickableObj>();
			this.iLoadCnt++;
			this.algmMenuList = new ArrayList<GMenu>();
			this.iLoadCnt++;
			
			this.bIsAnyBTConnectionCreated = this.geMain.isAnyBTConnectionCreated();
			if ( this.bIsAnyBTConnectionCreated ) {
				this.geMain.gnhHandler.gnbtHandler.pollAllMsg();
			}
			
			this.initVariables();
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameScene" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void destroy() {
		try {
			if ( this.alboBackGround != null ) {
				for ( BaseObject bo : this.alboBackGround ) {
					if ( bo != null ) {
						bo.destroy();
					}
				}
				
				this.alboBackGround.clear();
				this.alboBackGround = null;
			}
			
			if ( this.alboForeGround != null ) {
				for ( BaseObject bo : this.alboForeGround ) {
					if ( bo != null ) {
						bo.destroy();
					}
				}
				
				this.alboForeGround.clear();
				this.alboForeGround = null;
			}
			
			if ( this.alboSceneObj != null ) {
				for ( BaseObject bo : this.alboSceneObj ) {
					if ( bo != null ) {
						bo.destroy();
					}
				}
				
				this.alboSceneObj.clear();
				this.alboSceneObj = null;
			}
			
			if ( this.alcoClickableObj != null ) {
				for ( ClickableObj co : this.alcoClickableObj ) {
					if ( co != null ) {
						co.destroy();
					}
				}
				
				this.alcoClickableObj.clear();
				this.alcoClickableObj = null;
			}
			
			if ( this.algmMenuList != null ) {
				for ( GMenu gm : this.algmMenuList ) {
					if ( gm != null ) {
						gm.destroy();
					}
				}
				
				this.algmMenuList.clear();
				this.algmMenuList = null;
			}
			
			if ( this.gmNowShowing != null ) {
				this.gmNowShowing.destroy();
				this.gmNowShowing = null;
			}
			
			this.joNetwork = null;
			this.sParm = null;
			this.geMain = null;
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameScene.destroy" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void initVariables() {
		this.iResBGMusic = R.raw.backsound;
	}
	
	public GameEngine getGameEngine() {
		return this.geMain;
	}
	
	// Game Object
	protected void addSceneObj( BaseObject p_go ) {
		try {
			this.alboSceneObj.add( p_go );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameScene.addSceneObj" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	protected void addClickableObj( ClickableObj p_gb ) {
		try {
			this.alcoClickableObj.add( p_gb );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameScene.addClickableObj" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	protected void addBackGround( BaseObject p_go ) {
		try {
			this.alboBackGround.add( p_go );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameScene.addBackGround" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	protected void addForeGround( BaseObject p_go ) {
		try {
			this.alboForeGround.add( p_go );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameScene.addForeGround" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	protected void removeSceneObj( BaseObject p_go ) {
		try {
			this.alboSceneObj.remove( p_go );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameScene.removeSceneObj" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	protected void removeClickableObj( ClickableObj p_co ) {
		try {
			this.alcoClickableObj.remove( p_co );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameScene.removeClickableObj" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	protected void removeBackGround( BaseObject p_go ) {
		try {
			this.alboBackGround.remove( p_go );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameScene.removeBackGround" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	protected void removeForeGround( BaseObject p_go ) {
		try {
			this.alboForeGround.remove( p_go );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameScene.removeForeGround" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	protected BaseObject getSceneObj( int p_iIdx ) {
		return this.alboSceneObj.get( p_iIdx );
	}
	
	public void drawBackGround( Canvas p_c , Paint p_p ) {
		try {
			for ( BaseObject bo : this.alboBackGround ) {
				if ( bo != null ) {
					bo.draw( p_c , p_p );
				}
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameScene.drawBackGround" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void drawForeGround( Canvas p_c , Paint p_p ) {
		try {
			for ( BaseObject bo : this.alboForeGround ) {
				if ( bo != null ) {
					bo.draw( p_c , p_p );
				}
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameScene.drawForeGround" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	//@Override
	public void draw( Canvas p_c , Paint p_p ) {
		try {
			switch ( this.gssStatus ) {
			case loading:
				p_c.drawColor( color.black , PorterDuff.Mode.CLEAR );

				String msg = "Now Loading...(" + ( this.iLoadCnt * 100 / this.iLoadTotal ) + ")";
				Paint p = new Paint( p_p );
				float fTxtW;
				float fTxtH;
				GRectangle gr = new GRectangle( 0f , 0f , 0f , 0f ); 
				
				p.setColor( Color.WHITE );
				p.setTextSize( 80 );
				p.setTextAlign( Align.LEFT );
				
				fTxtW = p.measureText( msg );
				fTxtH = (float)(p.descent() - p.ascent());
				gr.set( this.geMain.gcScreenSize.fX + fTxtW , this.geMain.gcScreenSize.fY , this.geMain.gcScreenSize.fX , this.geMain.gcScreenSize.fY + fTxtH );
				gr.set( gr.convCoord( GOAnchor.DownRight ) );

				p_c.drawText( msg , gr.fLeft , gr.fDown , p );
				
				break;
			default:
				if ( p_c != null ) {
					p_c.drawColor( color.black , PorterDuff.Mode.CLEAR );
					this.drawBackGround( p_c , p_p );
					
					for ( BaseObject bo : this.alboSceneObj ) {
						if ( bo != null ) {
							bo.draw( p_c , p_p );
						}
					}
					
					for ( GMenu gm : this.algmMenuList ) {
						if ( gm != null ) {
							gm.draw( p_c , p_p );
						}
					}
					
					this.drawForeGround( p_c , p_p );
				}
				
				break;
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameScene.draw" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void preGameLoopLogic() {
		try {
			for ( BaseObject bo : this.alboBackGround ) {
				if ( bo != null ) {
					bo.preGameLoopLogic();
				}
			}
			
			for ( BaseObject bo : this.alboSceneObj ) {
				if ( bo != null ) {
					bo.preGameLoopLogic();
				}
			}
			
			for ( BaseObject bo : this.alboForeGround ) {
				if ( bo != null ) {
					bo.preGameLoopLogic();
				}
			}
			
			for ( GMenu gm : this.algmMenuList ) {
				if ( gm != null ) {
					gm.preGameLoopLogic();
				}
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameScene.preGameLoopLogic" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void gameLoopLogic() {
		try {
			for ( BaseObject bo : this.alboBackGround ) {
				if ( bo != null ) {
					bo.gameLoopLogic();
				}
			}
			
			for ( BaseObject bo : this.alboSceneObj ) {
				if ( bo != null ) {
					bo.gameLoopLogic();
				}
			}
			
			for ( BaseObject bo : this.alboForeGround ) {
				if ( bo != null ) {
					bo.gameLoopLogic();
				}
			}
			
			for ( GMenu gm : this.algmMenuList ) {
				if ( gm != null ) {
					gm.gameLoopLogic();
				}
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameScene.gameLoopLogic" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}

	public void postGameLoopLogic() {
		try {
			for ( BaseObject bo : this.alboBackGround ) {
				if ( bo != null ) {
					bo.postGameLoopLogic();
				}
			}
			
			for ( BaseObject bo : this.alboSceneObj ) {
				if ( bo != null ) {
					bo.postGameLoopLogic();
				}
			}
			
			for ( BaseObject bo : this.alboForeGround ) {
				if ( bo != null ) {
					bo.postGameLoopLogic();
				}
			}
			
			for ( GMenu gm : this.algmMenuList ) {
				if ( gm != null ) {
					gm.postGameLoopLogic();
				}
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameScene.postGameLoopLogic" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}

	public void processInput( TouchAction p_ta ) {
		try {
			for ( ClickableObj co : this.alcoClickableObj ) {
				if ( co != null ) {
					co.processInput( p_ta );
				}
			}
			
			for ( GMenu gm : this.algmMenuList ) {
				if ( gm != null ) {
					gm.processInput( p_ta );
				}
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameScene.processInput" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	//@Override
	public void onTouchEvent( MotionEvent p_me ) {
		// TODO Auto-generated method stub
		try {
			this.geMain.gtpHandler.addTouchAction( p_me );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameScene.onTouchEvent" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void backButtonHandler() {
		try {
			((GameMain)this.geMain.aApp).onBackPressedSuper();
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GameScene.backButtonHandler" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void pushMsgPre() {
	}
	
	public void readMsgPre() {
	}
	
	public void pushMsgPost() {
	}
	
	public void readMsgPost() {
	}
	
	public void setVarByNetwork() {
	}
}
